package br.edu.ufcg.greengrid.model.machine.state;

import br.edu.ufcg.greengrid.model.job.Job;
import br.edu.ufcg.greengrid.model.machine.Machine;

public abstract class AbstractMachineState implements MachineState {

	/*
	 * Here we aggregate all time spent in the state
	 */
	private long totalTimeSpent;
	
	/*
	 * In this case we only count the time spent since the last time we changed the state from another state to this one.
	 */
	private long timeSpent;

	protected long countdown;

	public AbstractMachineState() {
		this.totalTimeSpent = 0L;
	}

	public long getTotalTimeSpent() {
		return totalTimeSpent;
	}
	
	public long getTimeSpent() {
		
		return timeSpent;
	}

	public void setCountdown(long countdown) {
		this.countdown = countdown;
		this.timeSpent = 0;
	}

	protected boolean isCountdownZero(){
		return this.countdown == 0L;
	}
	
	// Operators that may change state
	public void update(Machine m) {
		this.totalTimeSpent++;
		this.timeSpent++;
		decCountdown();
		//XXX Maybe the case below happens when a machine is on state USER for a long time, doesn't it?
		if(this.countdown < 0){
			throw new IllegalStateException(String.format("Illegal countdown value: %d for machine: %s at state: %s", this.countdown, m.getId(), this.getClass().getName()));
		}
	}
	
	@Override
	public void changeStateIfNeeded(Machine m) {

	}

	protected void decCountdown() {
		this.countdown--;
	}

	public void setIdle(Machine m, long idletime) {

	}

	public void run(Machine m, Job job) {
		throw new IllegalStateException(getMessageForIllegalState(m));
	}

	public void wakeUp(Machine m) {
		throw new IllegalStateException(getMessageForIllegalState(m));
	}
	
	private String getMessageForIllegalState(Machine m) {
		return String.format("Illegal operation for state: %s for machine: %s", this.getClass().getName(), m.getId());
	}
	
}
